package org.cocos2dx.javascript;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.Gravity;

import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.games.Games;
import com.google.android.gms.games.GamesClient;
import com.google.android.gms.games.SnapshotsClient;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

import org.cocos2d.ShunLiu.R;

public class LogInManager {

    private static final String TAG = "UM.LogInManager";

    // Request code used to invoke sign in user interactions.
    private static final int RC_SIGN_IN = 9001;

    // Client used to sign in with Google APIs
    public GoogleSignInClient mGoogleSignInClient;

    // Client used to interact with Google Snapshots.
    private SnapshotsClient mSnapshotsClient = null;

    private static InstantAppActivity this_tmp;
    private static LogInManager mInstance = null;

    public static LogInManager getInstance() {
        if (null == mInstance) {
            mInstance = new LogInManager();
        }
        return mInstance;
    }

    public void init(InstantAppActivity context) {
        Log.d(TAG, "init");
        this.this_tmp = context;
    }

    /**
     * Start a sign in activity.  To properly handle the result, call tryHandleSignInResult from
     * your Activity's onActivityResult function
     */
    private void startSignInIntent() {
        this_tmp.startActivityForResult(mGoogleSignInClient.getSignInIntent(), RC_SIGN_IN);
    }

    /**
     * Try to sign in without displaying dialogs to the user.
     * <p>
     * If the user has already signed in previously, it will not show dialog.
     */
    public void signInSilently() {
        Log.d(TAG, "signInSilently()");

        mGoogleSignInClient.silentSignIn().addOnCompleteListener(this_tmp,
                new OnCompleteListener<GoogleSignInAccount>() {
                    @Override
                    public void onComplete(@NonNull Task<GoogleSignInAccount> task) {
                        if (task.isSuccessful()) {
                            Log.d(TAG, "signInSilently(): success");
                            onConnected(task.getResult());
                        } else {
                            Log.d(TAG, "signInSilently(): failure", task.getException());
                            onDisconnected();
                        }
                    }
                });
    }

    public static void signIn() {
        LogInManager.getInstance().startSignInIntent();
    }

    /**
     * 登出
     */
    public void signOut() {
        Log.d(TAG, "signOut()");

        mGoogleSignInClient.signOut().addOnCompleteListener(this_tmp,
                new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {

                        if (task.isSuccessful()) {
                            Log.d(TAG, "signOut(): success");
                        } else {
                            SavedGamesManager.getInstance().handleException(task.getException(), "signOut() failed!");
                        }

                        onDisconnected();
                    }
                });
    }

    public static void logOut() {
        LogInManager.getInstance().signOut();
    }

    /**
     * You can capture the Snapshot selection intent in the onActivityResult method. The result
     * either indicates a new Snapshot was created (EXTRA_SNAPSHOT_NEW) or was selected.
     */
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (requestCode == RC_SIGN_IN) {
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(intent);
            try {
                GoogleSignInAccount account = task.getResult(ApiException.class);
                onConnected(account);
            } catch (ApiException apiException) {
                String message = apiException.getMessage();
                if (message == null || message.isEmpty()) {
                    message = this_tmp.getString(R.string.signin_other_error);
                }

                onDisconnected();

                new AlertDialog.Builder(this_tmp)
                        .setMessage(message)
                        .setNeutralButton(android.R.string.ok, null)
                        .show();
            }
        } else {
            SavedGamesManager.getInstance().onActivityResult(requestCode, resultCode, intent);
        }
    }

    public void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate.");

        // Create the client used to sign in.
        mGoogleSignInClient = GoogleSignIn.getClient(this_tmp,
                new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
                        // Since we are using SavedGames, we need to add the SCOPE_APPFOLDER to access Google Drive.
                        .requestScopes(Drive.SCOPE_APPFOLDER)
                        .build());
    }

    public void onResume() {
        Log.d(TAG, "onResume()");

        // Since the state of the signed in user can change when the activity is not active
        // it is recommended to try and sign in silently from when the app resumes.
        signInSilently();
    }

    public void onStop() {
        SavedGamesManager.getInstance().onStop();
    }

    // The currently signed in account, used to check the account has changed outside of this activity when resuming.
    GoogleSignInAccount mSignedInAccount = null;

    /**
     * 登陆成功
     *
     * @param googleSignInAccount
     */
    private void onConnected(GoogleSignInAccount googleSignInAccount) {
        Log.d(TAG, "onConnected(): connected to Google APIs");
        //初始化事件管理器
        EventManager.getInstance().init(this_tmp, googleSignInAccount);
        if (mSignedInAccount != googleSignInAccount) {
            mSignedInAccount = googleSignInAccount;
            onAccountChanged(googleSignInAccount);
        }
    }

    /**
     * 用户账号改变
     *
     * @param googleSignInAccount
     */
    private void onAccountChanged(GoogleSignInAccount googleSignInAccount) {
        mSnapshotsClient = Games.getSnapshotsClient(this_tmp, googleSignInAccount);
        SavedGamesManager.getInstance().init(this_tmp, googleSignInAccount);

        // Sign-in worked!
        Log.d(TAG, "Sign-in successful! Loading game state from cloud.");
        //展示登出按钮
        showSignOutBar();

        SavedGamesManager.getInstance().loadFromSnapshot(null);
    }

    private void onDisconnected() {

        Log.d(TAG, "onDisconnected()");

        mSnapshotsClient = null;
        SavedGamesManager.getInstance().init(null);
        showSignInBar();
    }

    public boolean isSignedIn() {
        return mSnapshotsClient != null;
    }

    /**
     * Shows the "sign in" bar (explanation and button).
     */
    private void showSignInBar() {
        this_tmp.InfoToJs("LoginState", "");
    }

    /**
     * Shows the "sign out" bar (explanation and button).
     */
    private void showSignOutBar() {
        this_tmp.InfoToJs("LogoutState", "");
    }
}